package org.activequant.core.domainmodel.marketscanner;

import static org.activequant.util.tools.IdentityUtils.equalsTo;
import static org.activequant.util.tools.IdentityUtils.safeCompare;
import static org.activequant.util.tools.IdentityUtils.safeHashCode;

import java.util.LinkedList;
import java.util.List;

import org.activequant.core.domainmodel.InstrumentSpecification;
import org.activequant.core.types.TimeFrame;

public class MarketScan extends ScanDataEntity<MarketScan>{
	
	private static final long serialVersionUID = -8600374819004303005L;
	
	private List<MarketScanRow> rows=new LinkedList<MarketScanRow>();
	/**
	 * private TimeFrame timeFrame = TimeFrame.TIMEFRAME_1_TICK;
	 */
	private TimeFrame timeFrame = TimeFrame.TIMEFRAME_1_TICK;
	
	public List<MarketScanRow> getRows() {
		return rows;
	}
	
	public void setRows(List<MarketScanRow> rows) {
		this.rows = rows;
	}	
	/**
	 * returns the associated timeFrame(TimeFrame)
	 * @return
	 */
	public TimeFrame getTimeFrame() {
		return timeFrame;
	}
	/**
	 * sets the associated timeFrame(TimeFrame) with the given val(TimeFrame)
	 * @param val
	 */
	public void setTimeFrame(TimeFrame val) {
		timeFrame = val;
	}
	
	public MarketScan(){
	
	}
	public MarketScan(ScanCriteria scanCriteria){
		this.setScanCriteria(scanCriteria);
	}
	
	public void insertMarketScanRow(int rank, InstrumentSpecificationDetails specDetails, String distance, String benchmark, String projection, String legsStr){
		MarketScanRow msr=new MarketScanRow(/*rank,*/specDetails, distance, benchmark, projection, legsStr);
		//msr.setParent(this);
		if(rows.size()<getScanCriteria().getNumberOfRows()){
			rows.add(rank, msr);
		}else{
			rows.set(rank, msr);
		}
	}
	
	@Override
	public MarketScan clone() {
		MarketScan clone=new MarketScan(this.getScanCriteria());
		clone.rows.addAll(this.rows);
		return clone;
	}
	
	@Override
	public String toString() {
		return " ScanCriteria: "+this.getScanCriteria()+" timeStamp: "+this.getTimeStamp();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int hashCode() {
		// ATTENTION: keep in sync with compareTo();
		return safeHashCode(this.getScanCriteria()) + safeHashCode(this.getTimeStamp());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean equals(Object other) {
		// NOTE: delegates to compareTo()
		return equalsTo(this, other);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public int compareTo(MarketScan other) {
		// ATTENTION: keep in sync with hashCode();
		int rc;
		rc = safeCompare(this.getScanCriteria(), other.getScanCriteria());
		if (rc != 0) return rc;
		rc = safeCompare(this.getTimeStamp(), other.getTimeStamp());
		if (rc != 0) return rc;
		return rc;
	}	
	
	public void reset(){
		synchronized(rows){
			rows.clear();
		}
	}
	
	public int indexOf(InstrumentSpecification spec){
		int index=0;
		for(MarketScanRow row:getRows()){
			if(spec.getId().equals(row.getInstrumentSpecificationDetails().getId())){
//				return row.getRanking();
				return index;
			}
			index++;
		}
		return -1;
	}
	
	public int indexOf(InstrumentSpecificationDetails specDetails){
		int index=0;
		for(MarketScanRow row:getRows()){
			if(specDetails.getId().equals(row.getInstrumentSpecificationDetails().getId())){
//				return row.getRanking();
				return index;
			}
			index++;
		}
		return -1;
	}
	
}
